package com.yeskery.nut.extend.oauth;

/**
 * 访问令牌生成器
 * @param <T> 授权码请求对象
 * 2024/10/21
 */
public abstract class BaseAccessTokenGenerator<T extends BaseRequest> implements AccessTokenGenerator<T> {

    /** token保存接口 */
    private final TokenStore tokenStore;

    /** token过期时间 */
    private final long expires;

    /** token过期时间 */
    private final long refreshExpires;

    /**
     * 构造访问令牌生成器
     * @param tokenStore token存储接口
     * @param expires 访问token过期时间
     * @param refreshExpires 刷新token过期时间
     */
    protected BaseAccessTokenGenerator(TokenStore tokenStore, long expires, long refreshExpires) {
        this.tokenStore = tokenStore;
        this.expires = expires;
        this.refreshExpires = refreshExpires;
    }

    @Override
    public <R> AccessTokenResponse<R> generateAccessToken(T request, AuthTokenValueHandler authTokenValueHandler) {
        return generateAccessToken(authTokenValueHandler);
    }

    @Override
    public <R> AccessTokenResponse<R> generateAccessToken(AuthTokenValueHandler authTokenValueHandler) {
        AccessTokenResponse<R> response = createNewAccessToken();
        tokenStore.save(response.getAccessToken(), getAccessTokenValue(response, authTokenValueHandler), expires);
        tokenStore.save(response.getRefreshToken(), getRefreshTokenValue(response, authTokenValueHandler), refreshExpires);
        return response;
    }

    @Override
    public String getAccessTokenValue(String accessToken) {
        return tokenStore.get(accessToken);
    }

    @Override
    public boolean validateAccessToken(String accessToken) {
        return tokenStore.validate(accessToken);
    }

    /**
     * 获取token存储接口
     * @return token存储接口
     */
    public TokenStore getTokenStore() {
        return tokenStore;
    }

    /**
     * 获取过期时间
     * @return 过期时间
     */
    public long getExpires() {
        return expires;
    }

    /**
     * 获取刷新过期时间
     * @return 刷新过期时间
     */
    public long getRefreshExpires() {
        return refreshExpires;
    }

    /**
     * 获取访问token前缀
     * @return 访问token前缀
     */
    protected String getAccessTokenPrefix() {
        return "nut:oauth:access_token:";
    }

    /**
     * 获取刷新token前缀
     * @return 刷新token前缀
     */
    protected String getRefreshTokenPrefix() {
        return "nut:oauth:refresh_token:";
    }

    /**
     * 创建访问token
     * @return 访问token
     */
    protected abstract String createAccessToken();

    /**
     * 创建刷新token
     * @return 刷新token
     */
    protected String createRefreshAccessToken() {
        return createAccessToken();
    }

    /**
     * 获取访问token值
     * @param accessTokenResponse AccessToken响应对象
     * @param authTokenValueHandler 授权值处理器
     * @return 访问token值
     * @param <R> 响应类型
     */
    protected <R> String getAccessTokenValue(AccessTokenResponse<R> accessTokenResponse, AuthTokenValueHandler authTokenValueHandler) {
        return authTokenValueHandler == null ? "" : authTokenValueHandler.authTokenValue();
    }

    /**
     * 获取访问token值
     * @param accessTokenResponse AccessToken响应对象
     * @param authTokenValueHandler 授权值处理器
     * @return 访问token值
     * @param <R> 响应类型
     */
    protected <R> String getRefreshTokenValue(AccessTokenResponse<R> accessTokenResponse, AuthTokenValueHandler authTokenValueHandler) {
        return getAccessTokenValue(accessTokenResponse, authTokenValueHandler);
    }

    /**
     * 创建新的访问token
     * @return 访问token
     * @param <R> 响应类型
     */
    protected <R> AccessTokenResponse<R> createNewAccessToken() {
        AccessTokenResponse<R> response = new AccessTokenResponse<>();
        response.setTokenType("Bearer");
        response.setAccessToken(createAccessToken());
        response.setExpiresIn(expires);
        response.setRefreshToken(createRefreshAccessToken());
        return response;
    }
}
